;**********************************************
;*@File: ASCII2.asm
;*@Author: Scriptfan <scriptfan@hotmail.com>
;*@Date: 2017-1-11
;*@Description: 英文ASCII字符显示程序设计
;*              在5X7LED点阵中显示英文字符
;*              改进版，将字符显示代码放在独立的子程序
;**********************************************
	ORG 0000H
	LJMP MAIN
	ORG 0100H
MAIN:
	;设置栈底
	MOV SP, #05FH
	;设置主程序工作寄存器组为0
	CLR RS0
	CLR RS1
START:
	;设置要显示的字符的位置
	MOV R2, #00H
	;每个字符显示的时长
	MOV R3, #0FFH

LOOP:	
	MOV 032H, R2
	;显示字符
	LCALL DISPLAY
	DJNZ R3, LOOP
	
	;循环显示4个字符
	INC R2
	CJNE R2, #06H, LOOP
	SJMP START

	;终止
	SJMP EXIT

;字符显示子程序,机内码在RAM中起始位置为032H
;{*********************************************
DISPLAY:
	PUSH PSW
	PUSH ACC
	;使用工作寄存器组1
	CLR RS0
	SETB RS1
	;点阵字体存放位置
	MOV DPTR, #TABLE
	
	;计算字符起始偏移位置
	MOV A, 032H
	MOV B, #07H
	MUL AB
	ADD A, DPL
	MOV DPL, A
	MOV A, B
	ADDC A, DPH
	MOV DPH, A

	;初始化行选择状态
	MOV R4, #0FEH
	MOV R6, #00H

;逐行取出字符点阵信息
LINE:
	MOV A, R6
	MOV P1, R4
	;逐行取出点阵信息
	MOVC A, @A+DPTR
	MOV P3, A
	INC R6
	MOV A, R4
	RL A
	MOV R4, A

	;延时0.2ms
	MOV 030H, #01H
	LCALL DELAY

	CJNE R4, #0FEH, LINE
	POP ACC
	POP PSW
	RET
;}*********************************************

;延时子程序，延时Xms
;{*********************************************
DELAY:
	PUSH PSW
	PUSH ACC
	;使用工作寄存器组2
	SETB RS0
	CLR RS1
	;外部循环初值，从RAM地址03FH传入值
	MOV R7, 030H
LOOP1:	
	;内部循环初值
	MOV R6, #0FAH
LOOP2:
	DJNZ R6, LOOP2
	DJNZ R7, LOOP1
	POP ACC
	POP PSW
	RET
;}*********************************************

;ASCII字符点阵
;{*********************************************
TABLE:
	db	 04h, 0Ah, 11h, 11h, 1Fh, 11h, 11h  ; -A-
	db	 1Eh, 11h, 11h, 1Eh, 11h, 11h, 1Eh  ; -B-
	db	 0Eh, 11h, 10h, 10h, 10h, 11h, 0Eh  ; -C-
	db	 1Eh, 11h, 11h, 11h, 11h, 11h, 1Eh  ; -D-
	db	 1Fh, 10h, 10h, 1Eh, 10h, 10h, 1Fh  ; -E-
	db	 1Fh, 10h, 10h, 1Eh, 10h, 10h, 10h  ; -F-
;}*********************************************

EXIT:
	;程序退出
	END
